package com.vecspace.dayu.code.ui.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.vecspace.dayu.code.consts.*;
import com.vecspace.dayu.code.pojo.DataColumn;
import com.vecspace.dayu.code.pojo.DataTable;
import com.vecspace.dayu.code.pojo.Func;
import com.vecspace.utils.Convert;
import org.apache.commons.collections4.ListUtils;

import com.vecspace.dayu.code.template.pojo.TemplatePageComponent;
import com.vecspace.dayu.code.template.pojo.TemplatePageLayout;
import com.vecspace.dayu.code.ui.pojo.DataGrid;
import com.vecspace.dayu.code.ui.pojo.DataGridColumn;
import com.vecspace.dayu.code.ui.pojo.DataTree;
import com.vecspace.dayu.code.ui.pojo.Form;
import com.vecspace.dayu.code.ui.pojo.FormField;
import com.vecspace.dicttable.CodeItem;
import com.vecspace.dicttable.DictAll;
import org.apache.commons.lang3.StringUtils;

/** 
 * @version 1.0
 * @author wanghua
 */
public class PageConfigVO {
	private Func func;
	private Long tableId;
	private String terminalType;
	private List<DataColumn> tableColumns;
	private DataGrid dataGrid;
	private DataTree dataTree;
	private Form form;
	private final List<TemplatePageComponent> templatePageComponents = new ArrayList<>();
	private List<ColumnVO> columnVOList;

	private DataTable table;

	public PageConfigVO(){

	}
	public PageConfigVO(Func func, Long tableId){
		this.func = func;
		this.tableId = tableId;
	}

	public List<ColumnVO> getColumnVOList(){
		if(columnVOList == null)return Collections.emptyList();
		return Collections.unmodifiableList(columnVOList);
	}

	public void setColumnVOList(List<ColumnVO> columnVOList) {
		this.columnVOList = columnVOList;
	}

	public void buildColumnVOList(){
		columnVOList = new ArrayList<>();
		if(tableColumns != null){
			int ordnum = 0;
			for(DataColumn column : tableColumns){
				ordnum += 10;
				ColumnVO columnVO = new ColumnVO(column);
				columnVO.setGridColumnOrdnum(ordnum);
				columnVO.setFormFieldOrdnum(ordnum);
				if(dataGrid != null && dataGrid.getGridColumns() != null){
					DataGridColumn gridColumn = dataGrid.getGridColumns().stream().filter(it->column.getId().equals(it.getColumnId())).findAny().orElse(null);
					columnVO.putGridColumn(gridColumn);
				}
				if(form != null && form.getFormFields() != null){
					FormField formField = form.getFormFields().stream().filter(it->column.getId().equals(it.getColumnId())).findAny().orElse(null);
					columnVO.putFormField(formField);
				}
				columnVOList.add(columnVO);
			}
		}
		if(dataGrid == null || dataGrid.getGridColumns() == null || dataGrid.getGridColumns().size() == 0){
			this.choiceDefaultGridColumns();
			this.choiceDefaultQueryFieldColumns();
		}
		if(form == null || form.getFormFields() == null || form.getFormFields().size() == 0){
			this.choiceDefaultFormFieldColumns();
		}
	}


	/**默认表格列
	 *
	 */
	private void choiceDefaultGridColumns(){
		if(columnVOList == null)return;
		for(ColumnVO col : columnVOList){
			DataColumn dcol = col.getDataColumn();
			if(dcol.getIsKeyColumn())continue;
			if(dcol.getJsonIgnore())continue;
			if("ROW_LOCK".equalsIgnoreCase(col.getColumnName()))continue;
			if("TENANT_ID".equalsIgnoreCase(col.getColumnName()))continue;
			if(Convert.toInt(dcol.getDataLength(),0) > 200){
				continue;
			}
			if("ordnum".equalsIgnoreCase(dcol.getColumnName()) || "ordinal_".equalsIgnoreCase(dcol.getColumnName()) || "order_num".equalsIgnoreCase(dcol.getColumnName())) {
				continue;
			}
			col.setIsGridColumn(true);

			col.setEditMenu(dcol.getCellMenu());
			col.setAggregateGroup(dcol.getIsGroupby());
			col.setAggregateFunc(dcol.getAggregateFunc());
			col.setVisibleStatus(true);
			if(StringUtils.equalsIgnoreCase(col.getColumnName(), table.getNameColumnName())) {
				col.setFixed(true);
			}
			if(ColumnType.NAME_COLUMN.equals(dcol.getColumnType())) {
				col.setFixed(true);
				col.setColumnWidth(200);
			}

			if(StringUtils.isNotBlank(dcol.getCodeType())){
				col.setEditMenu(true);
			}
		}
	}

	/**默认表单项
	 *
	 */
	private void choiceDefaultFormFieldColumns(){
		if(columnVOList == null)return;
		for(ColumnVO col : columnVOList){
			DataColumn dcol = col.getDataColumn();
			if(dcol.getIsKeyColumn())continue;
			if(dcol.getJsonIgnore())continue;
			if("ROW_LOCK".equalsIgnoreCase(col.getColumnName()))continue;
			if("TENANT_ID".equalsIgnoreCase(col.getColumnName()))continue;
			if(table.getParentColumn() != null) {
				if(col.getColumnName().equalsIgnoreCase(table.getParentColumn().getColumnName())) {
					continue;
				}
			}
			col.setIsFormField(true);
			col.setRequired(dcol.getRequired());
			col.setValidationRules(dcol.getValidationRules());
			
			col.setFormElementType(dcol.getDefaultInputElementType());
			if(StringUtils.equalsIgnoreCase(col.getColumnName(), table.getNameColumnName())) {
				col.setRequired(true);
			}
			
			if(dcol.getDataLength() != null && dcol.getDataLength().intValue() > 100) {
				col.setColSpan(3);
				col.setNewRow(true);
			}
		}
	}

	/**默认查询项
	 *
	 */
	private void choiceDefaultQueryFieldColumns(){
		if(columnVOList == null)return;
		for(ColumnVO col : columnVOList){
			DataColumn dcol = col.getDataColumn();
			if(dcol.getIsKeyColumn())continue;
			if(dcol.getJsonIgnore())continue;
			if("ROW_LOCK".equalsIgnoreCase(col.getColumnName()))continue;
			if("TENANT_ID".equalsIgnoreCase(col.getColumnName()))continue;
			if(StringUtils.isBlank(col.getQuerySqlOperator())) {
				if(StringUtils.isNotBlank(dcol.getCodeType())){
					if(StringUtils.containsIgnoreCase(dcol.getSearchValueType(), "multi")){
						col.setQuerySqlOperator("in");
					}else {
						col.setQuerySqlOperator("equal");
					}
					col.setQueryInputElementType(QueryElementType.SELECT);
				}else if(dcol.getIsNumber()){
					col.setQuerySqlOperator("between");
					col.setQueryInputElementType(QueryElementType.FLOAT_INPUT);
				}else if(dcol.getIsDate() || dcol.getIsDateTime()){
					if(StringUtils.containsIgnoreCase(dcol.getSearchValueType(), "date-year")){
						col.setQuerySqlOperator("equal");
						col.setQueryInputElementType(QueryElementType.DATE_YEAR);
					}else if(StringUtils.containsIgnoreCase(dcol.getSearchValueType(), "date-month")){
						col.setQuerySqlOperator("equal");
						col.setQueryInputElementType(QueryElementType.DATE_MONTH);
					}else {
						col.setQuerySqlOperator("between");
						col.setQueryInputElementType(QueryElementType.DATE);
					}
				}else if(StringUtils.isNotBlank(dcol.getRefTableName())) {
					col.setQuerySqlOperator("equal");
					col.setQueryInputElementType(QueryElementType.SELECT);
				}else {
					if("String".equalsIgnoreCase(dcol.getJavaType())){
						
						col.setQuerySqlOperator("like");
						col.setQueryInputElementType(QueryElementType.TEXT_INPUT);
					}
				}
	
				if(StringUtils.containsIgnoreCase(dcol.getSearchValueType(), "required")){
					col.setQueryRequired(true);
				}
			}
			if(Convert.toBoolean(dcol.getIsSearchField(), false) == true){
				col.setQueryField(true);
			}
			if(StringUtils.equalsIgnoreCase(col.getColumnName(), table.getNameColumnName())) {
				col.setQueryField(true);
			}
			if(StringUtils.isNotBlank(col.getRefTableName())) {
				col.setQueryField(true);
			}
//			if(ColumnType.NAME_COLUMN.equals(dcol.getColumnType())) {
//				col.setQueryField(true);
//				col.setQuerySqlOperator("like");
//				col.setQueryInputElementType(QueryElementType.TEXT_INPUT);
//			}
//			if(StringUtils.isNotBlank(dcol.getCodeType())){
//				col.setQueryField(true);
//				col.setQuerySqlOperator("equal");
//				col.setQueryInputElementType(QueryElementType.SELECT);
//			}
//			if(ColumnType.REF_COLUMN.equals(dcol.getColumnType())) {
//				col.setQueryField(true);
//				col.setQuerySqlOperator("equal");
//				col.setQueryInputElementType(QueryElementType.SELECT);
//			}
		}
	}

	public void addTemplatePageComponents(List<TemplatePageComponent> templatePageComponents) {
		this.templatePageComponents.addAll(templatePageComponents);
	}

	public void setDataGrid(DataGrid dataGrid, List<DataGridColumn> gridColumns) {
		if(dataGrid == null)return;
		this.dataGrid = dataGrid;
		dataGrid.setGridColumns(gridColumns);
	}

	public void setForm(Form form, List<FormField> fields){
		if(form == null)return;
		form.setFormFields(fields);
		this.form = form;
	}

	public Form getForm() {
		return form;
	}

	public void setTableId(Long tableId) {
		this.tableId = tableId;
	}

	public void setDataGrid(DataGrid dataGrid) {
		this.dataGrid = dataGrid;
	}

	public void setForm(Form form) {
		this.form = form;
	}

	/**页面模板是否包含Tree
	 * @return 
	 * @author wanghua
	 */
	public boolean pageHasTree() {
		if(TablesRelation.CatalogAndLeaf.equals(func.getTablesRelation()))
		{
			return true;
		}
		return false;
	}

	public String getTerminalType() {
		return terminalType;
	}

	public void setTerminalType(String terminalType) {
		this.terminalType = terminalType;
	}

	public List<TemplatePageComponent> getTemplatePageComponents() {
		return ListUtils.unmodifiableList(templatePageComponents);
	}

	public boolean getExistTree() {
		return this.pageHasTree() && dataTree != null;
	}
	
	public List<CodeItem> getTerminalTypes(){
		List<CodeItem> items = DictAll.getItems(TemplatePageLayout.TerminalTypeCode, true).stream().collect(Collectors.toList());
		return items;
	}

	public List<CodeItem> getCellTextTypes(){
		List<CodeItem> items = DictAll.getItems(DataGridColumn.CellTextTypeCode, true).stream().collect(Collectors.toList());
		items.add(0, new CodeItem("", ""));
		return items;
	}

	public List<CodeItem> getInputElementTypes(){
		List<CodeItem> items = DictAll.getItems(DataGridColumn.InputElementTypeCode, true).stream().collect(Collectors.toList());
		items.add(0, new CodeItem("", ""));
		return items;
	}

	public List<CodeItem> getQuerySqlOperators(){
		List<CodeItem> items = DictAll.getItems(DataGridColumn.QuerySqlOperatorCode, true).stream().collect(Collectors.toList());
		items.add(0, new CodeItem("", ""));
		return items;
	}

	public List<CodeItem> getQueryElementTypes(){
		List<CodeItem> items = DictAll.getItems(DataGridColumn.QueryInputElementTypeCode, true).stream().collect(Collectors.toList());
		items.add(0, new CodeItem("", ""));
		return items;
	}
	
	public List<CodeItem> getFormElementTypes(){
		List<CodeItem> items = DictAll.getItems(FormField.FormElementTypeCode, true).stream().collect(Collectors.toList());
		items.add(0, new CodeItem("", ""));
		return items;
	}

	public List<CodeItem> getValidationRuleList(){
		List<CodeItem> items = DictAll.getItems(FormField.ValidationRulesCode, true).stream().collect(Collectors.toList());
		items.add(0, new CodeItem("", ""));
		return items;
	}

	public List<CodeItem> getAggregateFuncs(){
		List<CodeItem> items = DictAll.getItems(DataGridColumn.AggregateFuncCode, true).stream().collect(Collectors.toList());
		items.add(0, new CodeItem("", ""));
		return items;
	}

	public Long getTableId() {
		return tableId;
	}

	@JsonIgnore
	public List<DataColumn> getTableColumns() {
		return tableColumns;
	}

	public void setTableColumns(List<DataColumn> tableColumns) {
		this.tableColumns = tableColumns;
	}

	public DataGrid getDataGrid() {
		return dataGrid;
	}

	public DataTree getDataTree() {
		return dataTree;
	}

	public void setDataTree(DataTree dataTree) {
		this.dataTree = dataTree;
	}

	@JsonIgnore
	public DataTable getTable() {
		return table;
	}

	public void setTable(DataTable table) {
		this.table = table;
	}
}
